package high;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 47868
 */
public class ThreadPrint2 {
    public static AtomicInteger atomicInteger = new AtomicInteger(0);
    public static final Object OBJECT = new Object();
    public static ExecutorService executorService = Executors.newFixedThreadPool(5);
    public static final int MAX_NUMBER = 200;

    public static void main(String[] args) {
        Runnable runnable = () -> {
            while (true) {
                synchronized (OBJECT) {
                    // 检查是否已达到最大值
                    if (atomicInteger.get() > MAX_NUMBER) {
                        break;
                    }

                    System.out.println(Thread.currentThread().getName() + "打印出" + atomicInteger.getAndIncrement());

                    // 唤醒另一个线程
                    OBJECT.notify();

                    // 如果已经打印完最后一个数，退出前再次唤醒另一个线程
                    if (atomicInteger.get() > MAX_NUMBER) {
                        //在最后一次打印后唤醒另一个线程，防止其因等待而永久阻塞
                        OBJECT.notify();
                        break;
                    }

                    try {
                        OBJECT.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        };

        executorService.submit(runnable);
        // 使用同一个Runnable实例
        executorService.submit(runnable);

        // 等待所有任务完成
        executorService.shutdown();
        try {
            // 等待线程池中的任务执行完毕，最多等待3秒（时间可根据需求调整）
            if (!executorService.awaitTermination(3, TimeUnit.SECONDS)) {
                // 若超时仍未完成，可强制关闭（可选）
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
        /*try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }*/

        /*如果不加判断，该语句会最先输出，因为这是主线程输出，想要在末尾输出，需要确保子线程执行完成，可以调用.sleep方法，也可以添加线程池的等待强制关闭策略
        这里不建议使用.sleep方法，不确定程序执行的时间*/
        System.out.println("所有任务已完成");
    }
}